<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.staticfile.org/vue/3.0.5/vue.global.js"></script>
</head>

<body>
    <div id="app" class="demo">
        <button @click="changeValue()">changeValue</button>
        <button @click="changeObj()">changeObj</button>
    </div>

</body>
<script>

    const HelloVueApp = {
        name: 'app',
        setup() {
            // 1. 监听单个数据源
            const info = Vue.reactive({
                name: 'zy'
            })
            const name = Vue.ref('zy')
            //传入一个 getter 函数，该函数返回的是响应式对象 info 的name属性 
            Vue.watch(() => info.name, (newValue, oldValue) => {
                console.log('传入getter函数', `info 从${oldValue}变化到${newValue}`)
            })
            // 传入响应式对象
            Vue.watch(info, (newValue, oldValue) => {
                // 只能获取新旧值的响应式对象
                console.log('传入响应式', oldValue, newValue)
            })
            // 解构为 getter 函数可获取为普通对象
            Vue.watch(() => {
                return { ...info }
            }, (newValue, oldValue) => {
                console.log('解构', oldValue, newValue)
            })
            // 传入 ref
            Vue.watch(name, (newValue, oldValue) => {
                console.log('ref', newValue, oldValue)
            })

            function changeValue() {
                info.name = 'xh'
                name.value = 'xh'
            }

            // 2. 监听多个源 
            // 传入数组可监听多个源，回调中接收新旧值的两个数组
            Vue.watch([() => ({ ...info }), name], ([newInfo, newName], [oldInfo, oldName]) => {
                // 为变化的新旧值相同
                console.log('监听多个源')
            })

            // 3. 监听响应式对象
            // 在需要监听深层嵌套响应式对象时，我们需要传入配置对象 deep 参数进行深度监听，还可以通过immediate参数先执行一次回调
            const obj = Vue.reactive({
                name: 'zy',
                lick: {
                    js: false
                }
            })
           Vue.watch(() => ({ ...obj }), (newValue, oldVale) => {
                console.log(newValue, oldVale)
            }, {
                deep: true,
                immediate: true
            })
            function changeObj() {
                obj.lick.js = true
            }
            return {
                changeValue,
                changeObj
            }
        }
    }
    Vue.createApp(HelloVueApp).mount('#app')
</script>

</html>